package edu.fyvtc.javaweb.demo.controller;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;


//@Controller注解表明这个类是一个SpringMVC的控制器
//控制器主要负责与前端进行交互、调用业务代码
@Controller
public class HomeController {

    //@RequestMapping注解用来将url与java方法做绑定
    //本例中，@RequestMapping("/")将url中的根目录，绑定到home()方法。

    //@ResponseBody注解表示将这个方法的返回值直接返回给前端
    //没有@ResponseBody注解，Spring会默认方法返回的是视图

    //方法名没有特殊要求，不重复即可
    //本方法作为最简单的方法，不接受任何参数，返回一段固定的字符串
    @RequestMapping("/")
    @ResponseBody
    public String home() {
        return "I am home";
    }


    //@RequestMapping注解除了可以指定url的目录外，还可以指定请求的提交方式
    //本例中指定了只能处理目录为"/menu1"的GET请求，则不能处理其他路径的请求或其他类型的请求（如POST）
    //如果没有显式指定method，则默认为RequestMethod.GET
    @RequestMapping(value = "/menu1", method = RequestMethod.GET)
    @ResponseBody
    public String methodOfMenu1() {
        return "I am menu1";
    }


    //@RequestMapping注解除了可以指定url的目录外，还可以指定请求的提交方式
    //本例中指定了只能处理目录为"/menu2"的POST请求
    //本例中，前端GET请求：  127.0.0.1:8080  则会报错
    @RequestMapping(value = "/menu2", method = RequestMethod.POST)
    @ResponseBody
    public String menu2ForPost() {
        return "I am menu2";
    }


    //给方法加上入参，可以接收前端传入的同名参数
    //本例中在前端调用时加上  name=张三  如：127.0.0.1:8080/menu3?name=张三
    //则返回  "张三 : say Hello"
    @RequestMapping(value = "/menu3")
    @ResponseBody
    public String menu3WithParam(String name) {
        return name + " : say Hello";
    }


    //接收入参时，默认前端参数名与变量名一致
    //@RequestParam注解可以修改变量绑定的前端参数名
    //本例中在前端调用时加上  姓名=张三  如：127.0.0.1:8080/menu4?姓名=张三
    //则返回  "张三 : say Hello"
    @RequestMapping(value = "/menu4")
    @ResponseBody
    public String useOfRequestParam1(@RequestParam("姓名") String name) {
        return name + " : say Hello";
    }


    //@RequestParam注解绑定的参数，默认是必填的
    //可以通过  required=false  设置参数为非必填
    //本例中，前端GET请求： 127.0.0.1:8080/menu5  也能够正常返回
    //上例中，前端GET请求： 127.0.0.1:8080/menu4  则会报错
    @RequestMapping(value = "/menu5")
    @ResponseBody
    public String useOfRequestParam2(@RequestParam(value = "姓名", required = false) String name) {
        return name + " : say Hello";
    }


    //也可以同时接收多个入参
    //本例中前端调用时可以传入两个参数，如： 127.0.0.1:8080/menu6?姓名=张三&age=19
    //则返回  "张三 : say "I am 19 years old""
    @RequestMapping(value = "/menu6")
    @ResponseBody
    public String multiParams(@RequestParam("姓名") String name,
                              @RequestParam("age") Integer age) {
        return name + " : say \"I am " + age + " years old\"";
    }


    //没有ResponseBody注解，SpringBoot会将返回结果交给视图解析器
    //本项目以  thymeleaf  为例
    //本例没有入参，返回String
    //把返回的String值作为路径在resources/templates/目录下寻找对应的.html文件
    //本例中，对应的.html文件为  resources/templates/helloWorld.html
    @RequestMapping(value = "/menu7")
    public String homePage() {
        return "helloWorld";
    }


    //没有ResponseBody注解，SpringBoot会将返回结果交给视图解析器
    //本项目以  thymeleaf  为例
    //本例使用Model作为入参，返回String
    //把返回的String值作为路径在resources/templates/目录下寻找对应的.html文件
    //本例中，对应的.html文件为  resources/templates/myView.html
    //Model中的attribute可以在html中使用，以实现动态调整html的目的
    @RequestMapping("/menu8")
    public String htmlPageModel(Model model) {
        model.addAttribute("name", "熊大");
        return "myView";
    }

    //没有ResponseBody注解，SpringBoot会将返回结果交给视图解析器
    //本项目以  thymeleaf  为例
    //本例使用ModelAndView作为返回值
    //根据ModelAndView中的ViewName在resources/templates/目录下寻找对应的.html文件
    //本例中，对应的.html文件为  resources/templates/myView.html
    //ModelAndView中的attribute可以在html中使用，以实现动态调整html的目的
    @RequestMapping("/menu9")
    public ModelAndView htmlPageModelView() {
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.setViewName("myView");
        modelAndView.addObject("name", "熊二");
        return modelAndView;
    }
}